<?php
namespace App\Admin\Controllers\OverSeasIn;

use App\Exporter\OverSeasIn\OSBoxExporter;
use App\Importer\Delivery\FBAImporter;
use App\Models\Basics\PackingBox;
use App\Models\OverSeasIn\Delivery;
use App\Models\OverSeasIn\DeliveryBox;
use App\Models\OverSeasIn\DeliveryBoxDetail;
use App\Models\OverSeasIn\DeliveryDetail;
use App\Models\Product\ProductPackingBox;
use App\Util\RExcel;
use Encore\Admin\Controllers\AdminController;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Illuminate\Http\Request;
class OSBoxController extends AdminController{

    protected $title = '海外仓(中转)发货装箱单';

    public function update($id)
    {
        $name = request('name');
        $re = DeliveryBox::query()->find($id);
        $d = Delivery::query()->where('delivery_no',$re->delivery_no)->first();
        if($d->status != 4)return response()->json(['status' => false, 'message' => '操作失败：发货单状态有误！']);
        $value = request('value');
        if(in_array($name,['long','wide','high','weight'])){
            $flag = DeliveryBox::query()
                ->where('delivery_no' , $re->delivery_no)
                ->where('box_no' , $re->box_no)
                ->update([$name => $value]);
        }else{
            $re->{$name} = $value;
            $flag = $re->save();
        }
        if($flag){
            return response()->json(['status' => true, 'message' => '操作成功']);
        }else{
            return response()->json(['status' => false, 'message' => '操作失败']);
        }
    }

    public function download($id){
        $delivery = Delivery::query()->findOrFail($id);
        return Excel::download(new OSBoxExporter($delivery),$delivery->delivery_no.'-装箱信息.xlsx');
    }

    public function upload(Request $request){
        $file = $request->file('source_file');
        if ($file->isValid()) {
            $deliveryId = $request->get('delivery_id');
            $re = $this->_importFile($file,$deliveryId);
            if(is_array($re)) {
                if($re['flag']){
                    admin_toastr('文件：'.$re['data'].' 上传成功！');
                }else{
                    admin_toastr($re['data'],'error');
                }
            }else{
                return $re;
            }
        }else{
            admin_toastr('无效文件！','error');
        }
        return back()->withInput();
    }

    private function _importFile(UploadedFile $file,$deliveryId){
        try{
            $data = Excel::toArray(new FBAImporter(),$file);
            $data = $data[0];
            if(!$data)return ['flag' => false,'data' => '请上传包含有数据的文件！'];
            $delivery = Delivery::query()->find($deliveryId);
            if($delivery->status != 4)return ['flag' => false,'data' => '状态有误！'];
            $errors = [];
            $count = 1;
            $arr = [];
            DB::beginTransaction();
            $boxData = [];
            $boxNoTotal = [];
            $boxNoLong = [];
            $boxNoWide = [];
            $boxNoHigh = [];
            $boxNoWeight = [];
            $packingBoxId = PackingBox::getPackingBoxIdByAreaId($delivery->area_id);
            if(!$packingBoxId)return ['flag' => false,'data' => '该站点无装箱资料！'];
            foreach($data as $row){
                $count++;
                $boxNo = $row[0] ? trim($row[0]) : '';
                $total = $row[1] ? trim($row[1]) : '';
                unset($row[0]);
                unset($row[1]);
                if(!$boxNo || !$total){
                    $errors[$count] = '必填项为空';
                    continue;
                }
                if(!is_numeric($boxNo)){
                    $errors[$count] = '箱号必须为阿拉伯数字';
                    continue;
                }
                if(!in_array($boxNo,$arr)){
                    $arr[$count] = $boxNo;
                }else{
                    $errors[$count] = '重复记录';
                    continue;
                }
                $long = 0;
                $wide = 0;
                $high = 0;
                $weight = 0;
                $_boxData = [];
                $n = 0;
                while(true){
                    if(empty($row))break;
                    $_row = array_splice($row,0,2);
                    $fnSku = $_row[0] ? trim($_row[0]) : '';
                    $numPerBox = $_row[1] ? trim($_row[1]) : '';
                    if(!$fnSku){
                        continue;
                    }
                    $dd = DeliveryDetail::query()
                        ->where('delivery_no', $delivery->delivery_no)
                        ->where('fnsku', $fnSku)
                        ->first();
                    if(!$dd){
                        $errors[$fnSku] = $fnSku.'明细不存在';
                        continue;
                    }
                    $productPackingBox = ProductPackingBox::query()
                        ->where('packing_box_id',$packingBoxId)
                        ->where('psku_id' , $dd->psku_id)
                        ->first();
                    if(!$productPackingBox){
                        $errors[$fnSku] = $fnSku.'装箱资料不存在';
                        continue;
                    }
                    if($n == 0){
                        $long = $productPackingBox->box_long;
                        $wide = $productPackingBox->box_wide;
                        $high = $productPackingBox->box_high;
                        $weight = $productPackingBox->weight_per_box;
                    }
                    $_boxData[$fnSku]['account_id'] = $dd->account_id;
                    $_boxData[$fnSku]['psku_id'] = $dd->psku_id;
                    $_boxData[$fnSku]['total'] = $total;
                    $_boxData[$fnSku]['num_per_box'] = $numPerBox ?: $productPackingBox->num_per_box;
                    $n++;
                }
                if(!$long || !$wide || !$high || !$weight){
                    $errors[$count] = '箱规不能为空或0';
                    continue;
                }
                $boxData[$boxNo] = $_boxData;
                $boxNoTotal[$boxNo] = $total;
                $boxNoLong[$boxNo] = $long;
                $boxNoWide[$boxNo] = $wide;
                $boxNoHigh[$boxNo] = $high;
                $boxNoWeight[$boxNo] = $weight;
            }
            if(empty($boxData)){
                $errors[] = '无符合条件的数据';
            }
            if(!empty($errors)){
                return RExcel::importResult($errors);
            }
            foreach ($boxData as $boxNo => $boxDatum){
                $total = $boxNoTotal[$boxNo];
                foreach ($boxDatum as $fnSku => $item){
                    $boxItem = DeliveryBox::query()->firstOrNew([
                        'delivery_no' => $delivery->delivery_no,
                        'box_no' => $boxNo,
                        'fnsku' => $fnSku,
                    ],[
                        'batch_no' => $delivery->batch_no,
                        'delivery_type' => $delivery->delivery_type,
                        'plat_id' => $delivery->plat_id,
                        'area_id' => $delivery->area_id,
                        'warehouse_id' => $delivery->warehouse_id,
                        'psku_id' => $item['psku_id'],
                        'account_id' => $item['account_id'],
                        'total' => $total,
                        'num_per_box' => $item['num_per_box'],
                    ]);
                    $flag = $boxItem->save();
                    if(!$flag){
                        DB::rollBack();
                        continue;
                    }
                }
                $long = $boxNoLong[$boxNo];
                $wide = $boxNoWide[$boxNo];
                $high = $boxNoHigh[$boxNo];
                $weight = $boxNoWeight[$boxNo];
                $boxes = DeliveryBox::query()
                    ->where('delivery_no' , $delivery->delivery_no)
                    ->where('box_no' , $boxNo)
                    ->get();
                foreach ($boxes as $box){
                    $box->total = $total;
                    $box->long = $long;
                    $box->wide = $wide;
                    $box->high = $high;
                    $box->weight = $weight;
                    $box->save();
                    DeliveryBoxDetail::query()
                        ->where('delivery_box_id',$box->id)
                        ->where('p_index','>',$box->total)
                        ->delete();
                    for($index = 1; $index <= $box->total; $index++){
                        $indexCount = DeliveryBoxDetail::query()
                            ->where('delivery_box_id' , $box->id)
                            ->where('p_index' , $index)
                            ->count();
                        if($indexCount == 0){
                            DeliveryBoxDetail::query()->create([
                                'delivery_box_id' => $box->id,
                                'p_index' => $index,
                            ]);
                        }
                    }
                }
            }
            $totalBox = DeliveryBox::query()->where('delivery_no',$delivery->delivery_no)->sum('total');
            $delivery->total_box = $totalBox;
            $flag2 = $delivery->save();
            if($flag2){
                DB::commit();
            }else{
                DB::rollBack();
            }
            if(empty($errors)){
                return ['flag' => true,'data' => $file->getClientOriginalName()];
            }else{
                return RExcel::importResult($errors);
            }
        }catch(\Exception $e){
            DB::rollBack();
            report($e);
            return ['flag' => false,'data' => '系统异常！'];
        }
    }

    public function template(Request $request){
        $temp = $request->get('temp');
        $suffix = $request->get('suffix','xlsx');
        return Storage::disk('admin')->download("template/{$temp}-template.{$suffix}");
    }
}
